﻿/**
 * ...
 * @author aboutwhat
 */

package bloom.test.performance;
import bloom.lang.DoubleIterator;
import haxe.Timer;

using StringTools;

class PerformanceTest 
{
    
    public static function run (tests : Iterable<Int->Void>, ?names : Iterable<String>, ?name:String, ?loops = 100000) 
    {
        if (names == null) {
            var a = [];
            var i = 1;
            for ( t in tests) {
                a.push("Test " + i++);
            }
            names = a;
        }
        var p = new PerformanceTest(name, loops);
        for ( e in new DoubleIterator(tests, names) ) {
            p.addTest(e.e1, e.e2);
        }
        p.start();
    }
    
    var tests : Array<{name:String, test:Int->Void, time:Null<Float>}>;
    
    var loops : Int;
    var name : String;
    
    
    public function new (?name:String = "Default", ?loops = 100000) 
    {   
        this.name = name;
        tests = [];
        this.loops = loops;
    }
    
    public function addTest (a : Int -> Void, name:String) 
    {
        tests.push({name:name, test:a, time : null});
    }
    
    public function start () {
        
        trace("---------------------------------------");
        trace("Test: " + name);
        trace("---------------------------------------");
        var count = 1;
        
        for (i in tests) 
        {
            var time = Timer.stamp();
            i.test(loops);
            time = Timer.stamp() - time;
            
            
            time = Math.round(time * 10000) / 10000;
            if (time < 0.00001) time = 0.00001;
            i.time = time;
            trace(StringTools.rpad(count + ") " + i.name, " ", 21) + "" + time);
            count++;
        }
        trace("---------------------------------------");
        trace("Relative Results (Reference = 1)");
        tests.sort ( function (a, b) return (a.time < b.time) ? -1 : (a.time > b.time) ? 1 : 0);
        
        var ref = tests[0].time;
        
        var count = 1;
        for ( i in tests) {
            var percent = Std.string(Math.round((i.time / ref) * 10000) / 10000);
            if (percent.indexOf(".") == -1) {
                percent += ".";
            }
            
            while (percent.indexOf(".") > percent.length -5) {
                percent += "0";
            }
            
            percent = percent.lpad(" ", 3);
            
            
            trace(StringTools.rpad(count + ") " + i.name, " ", 20) +  " " + percent);
            count++;
        }
        
        
        
        
    }
    
    
}